package com.damage.purchase_dept.service.impl;

import com.damage.common.config.OrderConfig;
import com.damage.common.config.PurchasePlanConfig;
import com.damage.common.entity.Order;
import com.damage.common.entity.PurchasePlan;
import com.damage.common.entity.PurchasePlanDetail;
import com.damage.common.entity.SupplyGood;
import com.damage.common.exception.IncorrectPriceException;
import com.damage.common.exception.IncorrectStateException;
import com.damage.common.exception.ObsoleteException;
import com.damage.common.service.IPublicService;
import com.damage.purchase_dept.mapper.IPurchasePlanDetailMapper;
import com.damage.purchase_dept.mapper.IPurchasePlanMapper;
import com.damage.purchase_dept.service.IOrderService;
import com.damage.purchase_dept.service.IPurchasePlanService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class PurchasePlanServiceImpl implements IPurchasePlanService {

    @Autowired
    private IPurchasePlanMapper purchasePlanMapper;

    @Autowired
    private IPurchasePlanDetailMapper purchasePlanDetailMapper;

    @Autowired
    private IPublicService publicService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    PurchasePlanConfig purchasePlanConfig;

    @Autowired
    OrderConfig orderConfig;

    @Value("${pageSize}")
    private Integer pageSize;

    @Override
    @Transactional
    public Integer newPurchasePlan(PurchasePlan purchasePlan)
            throws IncorrectPriceException,ObsoleteException {
        //检查采购计划的价格
        checkPrice(purchasePlan);
        //检查采购计划是否过时
        checkObsolete(purchasePlan);
        //持久化采购计划
        purchasePlanMapper.insert(purchasePlan);
        List<PurchasePlanDetail> details = purchasePlan.getDetails();
        Integer purchasePlanId = purchasePlan.getId();
        for (PurchasePlanDetail detail : details) {
            detail.setPurchasePlanId(purchasePlanId);
        }
        //持久化采购计划详情
        purchasePlanDetailMapper.insertBatch(details);
        return purchasePlanId;
    }

    @Override
    public Integer setProcessInstanceId(Integer purchasePlanId, String processInstanceId) {
        return purchasePlanMapper.setProcessInstanceId(purchasePlanId,processInstanceId);
    }

    @Override
    public PageInfo<PurchasePlan> findByState(Integer pageNum, Integer state) {
        if (pageNum == null) {
            pageNum = 1;
        }
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<PurchasePlan> pageInfo = new PageInfo<>(purchasePlanMapper.findByState(state));
        return pageInfo;
    }

    @Override
    public PurchasePlan findById(Integer purchasePlanId) {
        return purchasePlanMapper.findById(purchasePlanId);
    }

    @Override
    public PurchasePlan findDetailedPurchasePlanById(Integer purchasePlanId) {
        PurchasePlan purchasePlan = purchasePlanMapper.findById(purchasePlanId);
        List<PurchasePlanDetail> details = purchasePlanDetailMapper.findByPurchasePlanId(purchasePlanId);
        purchasePlan.setDetails(details);
        return purchasePlan;
    }

    @Override
    @Transactional
    public Integer update(PurchasePlan purchasePlan) throws IncorrectPriceException, IncorrectPriceException {
        if (purchasePlan.getState() != PurchasePlanConfig.UNAUDITED
                && purchasePlan.getState() != PurchasePlanConfig.AUDITED_NOT_PASS) {
            throw new IncorrectStateException("采购计划不是未审核状态或者审核失败状态，不能够更新！");
        }
        checkPrice(purchasePlan);
        checkObsolete(purchasePlan);

        //更新采购计划
        Integer result = purchasePlanMapper.update(purchasePlan);

        List<PurchasePlanDetail> newDetails = purchasePlan.getDetails();
        List<PurchasePlanDetail> oldDetails = purchasePlanDetailMapper.findByPurchasePlanId(purchasePlan.getId());
        //新的详情是否已经存在
        boolean ifExist;
        for (PurchasePlanDetail newDetail : newDetails) {
            ifExist = false;
            for (PurchasePlanDetail oldDetail : oldDetails) {
                if (oldDetail.getSupplyGood().getId()
                        == newDetail.getSupplyGood().getId()) {
                    ifExist = true;
                    purchasePlanDetailMapper.update(newDetail);
                    break;
                }
            }
            if (ifExist == false) {
                newDetail.setPurchasePlanId(purchasePlan.getId());
                purchasePlanDetailMapper.insertOne(newDetail);
            }
        }

        //旧的详情是否已经失效
        boolean ifInvalid;
        for (PurchasePlanDetail oldDetail : oldDetails) {
            ifInvalid = true;
            for (PurchasePlanDetail newDetail : newDetails) {
                if (oldDetail.getSupplyGood().getId()
                        == newDetail.getSupplyGood().getId()) {
                    ifInvalid = false;
                    break;
                }
            }
            if (ifInvalid == true) {
                purchasePlanDetailMapper.deleteById(oldDetail.getId());
            }
        }

        return result;
    }

    @Override
    @Transactional
    public Integer deleteById(Integer purchasePlanId) throws IncorrectStateException {
        Integer deleteCount = 0;
        PurchasePlan purchasePlan = purchasePlanMapper.findById(purchasePlanId);
        if (purchasePlan.getState() == PurchasePlanConfig.GENERATE) {
            List<Order> orders = orderService.findByPurchasePlanId(purchasePlanId);
            for (Order order : orders) {
                if (order.getState() == OrderConfig.SENT
                        || order.getState() == OrderConfig.FINISH) {
                    throw new IncorrectStateException("此采购计划生成的订单已发送或者已完成，不能删除！");
                }
            }
            //删除采购计划对应的订单
            deleteCount += orderService.deleteByPurchasePlanId(purchasePlanId);
        }
        //删除采购计划详情
        deleteCount += purchasePlanDetailMapper.deleteBatchByPurchasePlanId(purchasePlanId);
        //删除采购计划
        deleteCount += purchasePlanMapper.deleteById(purchasePlanId);
        return deleteCount;
    }

    private void checkPrice(PurchasePlan purchasePlan) throws IncorrectPriceException {
        //计算金额，用数据库最新的数据对前端传来的数据进行更新。
        List<PurchasePlanDetail> details = purchasePlan.getDetails();
        Double totalPrice = 0d;
        for (PurchasePlanDetail detail : details) {
            Integer supplyGoodId = detail.getSupplyGood().getId();
            SupplyGood supplyGood = publicService.findSupplyGoodById(supplyGoodId);

            //判断数据库的商品价格和前端传来的商品价格是否相等
            if (supplyGood.getPrice().doubleValue()
                    != detail.getSupplyGood().getPrice().doubleValue()) {
                throw new IncorrectPriceException("供应商品的价格和数据库的价格不一样!");
            }
            //判断数据库计算的详情价格和前端传来的详情的价格是否相等
            Double price = supplyGood.getPrice() * detail.getCount();
            if (price.doubleValue()
                    != detail.getPrice().doubleValue()) {
                throw new IncorrectPriceException("采购计划详情的价格和数据库计算的价格不一样!");
            }
            totalPrice += price;
        }

        //判断后端计算的总价是否和前端传来的数据相同
        if (totalPrice.doubleValue()
                != purchasePlan.getTotalPrice().doubleValue()) {
            throw new IncorrectPriceException("采购计划的总价和数据库计算的结果不一样!");
        }
    }

    private void checkObsolete(PurchasePlan purchasePlan) throws ObsoleteException{
        List<PurchasePlanDetail> details = purchasePlan.getDetails();
        for (PurchasePlanDetail detail : details) {
            SupplyGood supplyGood = publicService.findSupplyGoodById(detail.getSupplyGood().getId());
            if (supplyGood.getNextRecordId() != null){
                throw new ObsoleteException("采购计划中的供应商品记录过时,不能添加采购计划！");
            }
        }

    }
}
